package com.cskaoyan.javase.oop3._2inner._3local._2usecase;

/**
 * 局部内部类经常使用在以下两个场景中：
 *      1.方法需要返回一个对象，返回值类型是引用数据类型时。
 *      方法需要返回一个对象时，可以在方法的局部位置写一个 局部内部类 继承/实现外部的类/接口创建对象后作为返回值。
 *      这是因为方法的返回值可以是返回值类型的对象，也可以是子类对象（当返回值类型是引用数据类型时）。
 *
 *      2.方法需要传入一个对象，形参数据类型是引用数据类型时。
 *      方法需要传入一个对象实参时，可以在调用方法的位置定义一个 局部内部类 来继承/实现外部的类/接口
 *      创建对象后作为方法的实参传入。
 *      这是因为方法的实参可以是形参类型的对象，也可以子类对象（当返回值类型是引用数据类型时）。
 *
 * 使用局部内部类的优点：
 *      1.绝对对外界隐藏，封装。
 *      2.相比较于传统的定义类，然后创建对象，它相对更加简洁省事。(简洁了一点,但并不多)
 * 缺点：
 *      这个类是一次性的。
 *
 * 综上，假如在局部位置需要一次性的使用某个对象，可以使用局部内部类创建它
 * 但是如果多次在不同的方法中使用，使用局部内部类就得不偿失了。
 *
 * @since 09:53
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        method().test();
        // 调用test(IA)方法,需要传入接口的实现类/子类对象
        method(new IAImpl());
        // 假如希望该实现类被隐藏,可以选择使用局部内部类
        class IAImpl implements IA{
            @Override
            public void test() {
                System.out.println("局部内部类的实现");
            }
        }
        method(new IAImpl());
    }

    public static void method(IA ia) {
        ia.test();
    }

    public static A method() {
        // return new A();
        // 还可以返回A的子类对象
        // return new ASon();
        // 假如希望A的子类被隐藏,可以使用局部内部类
        class ASon extends A {
            @Override
            void test() {
                System.out.println("ASon但是局部内部类");
            }
        }
        return new ASon();
    }
}

// 常规做法
class IAImpl implements IA{
    @Override
    public void test() {
        System.out.println("常规定义实现类做法");
    }
}
interface IA {
    void test();
}

// 常规做法
class ASon extends A {
    @Override
    void test() {
        System.out.println("ASon");
    }
}

class A {
    void test() {
        System.out.println("A");
    }
}
